﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Net;
using System.Text;
using System.IO;
using System.Xml;
using System.ComponentModel;
using System.Threading;

namespace Bing4Free
{
	public static class Bing4FreeDownloader
	{
		private static List<Wallpaper> wallpapers = new List<Wallpaper>();
		private static int downloadStatus = -1;

		private class Wallpaper
		{
			public string Path { get; set; }
			public string FileName { get; set; }
			public string Title { get; set; }
			public string FileDate { get; set; }
		}

		private delegate void updateWallpaperThumbnailListViewDelegate();
		private static void updateWallpaperThumbnailListView(bool isRefresh)
		{
			updateWallpaperThumbnailListViewDelegate updateWallpaperThumbnailListView = delegate()
			{
				MainForm.Instance.settingsTab.Enabled = true;
				MainForm.Instance.WallpaperThumbnailListView.Enabled = !isRefresh;

				if (isRefresh)
				{
					MainForm.Instance.WallpaperThumbnailListView.Items.Clear();
					new Thread(MainForm.Instance.LoadThumbnail).Start();
				}
			};

			MainForm.Instance.Invoke(updateWallpaperThumbnailListView);
		}

		private delegate void updateStatusTextDelegate();
		private static void updateStatusText(string statusText, bool showBalloon)
		{
			updateStatusTextDelegate updateStatusText = delegate()
			{
				MainForm.Instance.StatusLabel.Text = statusText;
				if (MainForm.Instance.WindowState == System.Windows.Forms.FormWindowState.Minimized)
				{
					if (showBalloon)
					{
						MainForm.Instance.NotifyIcon.BalloonTipText = statusText;
						MainForm.Instance.NotifyIcon.ShowBalloonTip(5);
					}
				}
			};

			MainForm.Instance.Invoke(updateStatusText);
		}

		public static void DownloadWallpaper()
		{
			int wallpaperCount = 0;

			if (WindowsAPI.IsConnectedToInternet())
			{
				searchWallpaper();

				downloadStatus = 0;

				if (wallpapers.Count > 0)
				{
					wallpaperCount = wallpapers.Count;
					updateStatusText("Wow, found " + wallpapers.Count.ToString() + " new wallpaper(s)", true);
					Thread.Sleep(1000);

					while (wallpapers.Count > 0)
					{
						if (downloadStatus == 0)
						{
							Thread.Sleep(500);
							string creationDate = string.Empty;
							downloadStatus = 1;
							try
							{
								if (!string.IsNullOrEmpty(wallpapers[0].FileDate))
								{
									creationDate = wallpapers[0].FileDate.Substring(0, 4) + "-" + wallpapers[0].FileDate.Substring(4, 2) + "-" + wallpapers[0].FileDate.Substring(6, 2);
								}

								Thread th = new Thread(downloadWallpaper);
								th.Start(new string[] { wallpapers[0].Path, Path.Combine(Bing4FreeSettings.settings.PicturesFolder, wallpapers[0].FileName), wallpapers[0].FileName, creationDate });
							}
							catch (Exception ex)
							{
								string error = ex.Message;
							}
						}
					}

					Thread.Sleep(1000);
					updateStatusText("Bravo, download completed", true);
				}
				else
				{
					Thread.Sleep(1000);
					updateStatusText("Oops, no new wallpaper or destination can't reachable", false);
				}
			}
			else
			{
				updateStatusText("Oops, no internet connection", false);
			}

			Thread.Sleep(2000);
			updateStatusText("", false);
			downloadStatus = -1;
			MainForm.Instance.IsBeginDownload = false;
			updateWallpaperThumbnailListView(WindowsAPI.IsConnectedToInternet() && wallpaperCount > 0);
		}

		private static void searchWallpaper()
		{
			string[] countries = Bing4FreeSettings.settings.Country.Split(',');

			foreach (string country in countries)
			{
				int currentIndex = 0;
				bool isImageAvailable = true;

				while (isImageAvailable)
				{
					WebRequest req = WebRequest.Create(string.Format("http://www.bing.com/HPImageArchive.aspx?format=xml&idx={0}&n=8&mkt={1}", currentIndex, country));

					using (WebResponse res = req.GetResponse())
					{
						using (StreamReader sr = new StreamReader(res.GetResponseStream(), Encoding.GetEncoding("utf-8")))
						{
							string srText = sr.ReadToEnd();

							if (srText.Length > 0)
							{
								XmlDocument bingXml = new XmlDocument();
								bingXml.LoadXml(srText);
								XmlNodeList bingNodes = bingXml.GetElementsByTagName("image");

								foreach (XmlNode bingNode in bingNodes)
								{
									string url = bingNode.SelectSingleNode("url").InnerText;
									string filename = url.Substring(url.LastIndexOf("/") + 1, url.Length - url.LastIndexOf("/") - 1).Split('_')[0] + ".jpg";

									if (!isWallpaperExist(filename))
									{
										Thread.Sleep(200);
										wallpapers.Add(new Wallpaper
										{
											Path = @"http://www.bing.com" + url,
											FileName = filename,
											Title = bingNode.SelectSingleNode("copyright").InnerText,
											FileDate = bingNode.SelectSingleNode("startdate").InnerText
										});
									}
								}

								if (bingNodes.Count < 8)
								{
									isImageAvailable = false;
								}
								else
								{
									currentIndex += 8;
								}
							}
							else
							{
								isImageAvailable = false;
							}
						}
					} // End GetResponse
				} // End While
			}
		}

		private static bool isWallpaperExist(string wallpaperName)
		{
			foreach (Wallpaper wallpaper in wallpapers)
			{
				if (wallpaper.FileName == wallpaperName)
				{
					return true;
				}
			}

			string[] localWallpaperCollection = Directory.GetFiles(Bing4FreeSettings.settings.PicturesFolder, "*.jpg");

			foreach (string localWallpaper in localWallpaperCollection)
			{
				DirectoryInfo di = new DirectoryInfo(localWallpaper);
				FileInfo fi = new FileInfo(di.FullName);

				if (fi.Name.Trim() == wallpaperName.Trim())
				{
					return true;
				}
			}

			return false;
		}

		private static void downloadWallpaper(object downloadInfo)
		{
			try
			{
				string[] dlInfo = (string[])downloadInfo;

				using (WebClient client = new WebClient())
				{
					if (MainForm.Instance.ProxyEnabled)
					{
						WebProxy proxy = new WebProxy(MainForm.Instance.ProxyServer, MainForm.Instance.ProxyPort);

						if (!string.IsNullOrEmpty(MainForm.Instance.Username) && !string.IsNullOrEmpty(MainForm.Instance.Password))
						{
							if (!MainForm.Instance.Username.Contains(@"\"))
							{
								proxy.Credentials = new NetworkCredential(MainForm.Instance.Username, MainForm.Instance.Password);
							}
							else
							{
								string[] userInfo = MainForm.Instance.Username.Split('\\');
								proxy.Credentials = new NetworkCredential(userInfo[1], MainForm.Instance.Password, userInfo[0]);
							}
						}

						client.Proxy = proxy;
					}

					client.DownloadFileAsync(new Uri(dlInfo[0]), dlInfo[1], dlInfo);
					client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
				}
			}
			catch (Exception ex)
			{
				string error = ex.Message;
			}
		}

		private static void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
		{
			string[] dlInfo = (string[])e.UserState;
			if (!string.IsNullOrEmpty(dlInfo[3]))
			{
				File.SetCreationTime(dlInfo[1], DateTime.Parse(dlInfo[3]));
				File.SetLastWriteTime(dlInfo[1], DateTime.Parse(dlInfo[3]));
				File.SetLastAccessTime(dlInfo[1], DateTime.Parse(dlInfo[3]));
			}
			wallpapers.RemoveAt(0);
			downloadStatus = 0;

			updateStatusText("Download " + dlInfo[2] + " ...", false);
		}

	}
}